#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

//题目一: 算出以下代码的结果
/*
int main() {
	int a, b, c;
	a = 5;   //++在前先加后用，++在后先用后加
	c = ++a;//c=6 a=6
	b = ++c, c++, ++a, a++;// 2逗号表达式：从左向右依次计算，整个表达式结果一定是最后一个表达式
	   // c=7 => c=8 ,  a=7 (8)  , b=7
	b += a++ + c;  //   a++ + c  => 8+8=16   b+ =16  => b=7+16=23  a=9(自增)
	printf("a=%d b=%d c=%d\n:", a, b, c);
	return 0;
}
*/

// 题目二:写一个承数返回参数二进制中1的个数
//比如：15 00001111 4个1
//NumberOf1就是计算参数n的二进制补码中有几个1
//123
//123%10=3
//123/10=12
//12%10=2
//12/10=1
//1%10=1
//1/10=0

//15 -00001111
//15%2=1
//15/2=7  -00000111
//7%2=1
//7/2=3  --00000011
//3%2=1  --00000001
//3/2=1  --00000001
//1%2=1  --00000001
//1/2=0	 --00000000

//14 -00001110
//14%2=0
//14/2=7  -00000111

/*
//方法一：对正数管用 负数不行 (返回类型改成  unsigned int 无符号整形 就可以)

 //int n = -l;
//10000000000000000000000000000001 源码   符号位不变，其余取反 =》反码
//11111111111111111111111111111110 反码 +1 =》补码
// 1111111111111111111111111111111  补码  
//负数 看补码 （32个1）
int NumberOf1(int n)
{
	int count = 0;
	while (n)  // 首先看n是不是零
	{
		if (n%2==1) //%2之后得到的一个数字是1的时候

		{
			count++; //说明二进制数中有1，计数器加一
		}
		n /= 2; //去掉一位 算下一位（最终变成零）
	}
	return count;
}
*/
/*
//方法二：
int NumberOf1(int n)
{
	int count = 0;
	int i = 0;
	for ( i = 0; i < 32; i++) //按位与，移动i位，i循环32次
	{
		if(( (n >> i)&1)== 1) //向右移动
		{
			count++;     
		}
	}
	return count;
}
*/


//方法三：
//  n-n&(n-1)
// n=15
// 1111 - n
// 1110 - n-1
// 1110 - n
// 1101 - n-1
// 1100 - n
// 1011 - n-1
// 1000 - n
// 0111 - n-1
// 0000 - n
//每次n - 1都会错位一个‘1’，按位于操作一下，错位的‘1’就变成‘0’
//如此循环，最终就会全部是 0
int NumberOf1(int n)
{
	int count = 0;
	int i = 0;
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	return count;
}

int main() {
	int n = 10; // 2的3次方+2的1次方 =》  1010 
	int ret = NumberOf1(n);
	printf("ret=%d\n", ret);
	return 0;
}



// 题三：写一个代码判断一个数字是不是2的n次方
//2的n次方的数字，其中只有一个1
//000010000  （这个一才代表的是二的几次方

//  k & (k-1) ==0   //二进制中
 